<script setup lang="ts">
import { ref } from 'vue'
{{#if (eq backend "convex")}}
import { api } from "@{{ projectName }}/backend/convex/_generated/api";
import type { Id } from "@{{ projectName }}/backend/convex/_generated/dataModel";
import { useConvexMutation, useConvexQuery } from "convex-vue";

const { data, error, isPending } = useConvexQuery(api.todos.getAll, {});

const newTodoText = ref("");
const { mutate: createTodo, isPending: isCreatePending } = useConvexMutation(api.todos.create);

const { mutate: toggleTodo } = useConvexMutation(api.todos.toggle);
const { mutate: deleteTodo, error: deleteError } = useConvexMutation(
  api.todos.deleteTodo,
);

function handleAddTodo() {
  const text = newTodoText.value.trim();
  if (!text) return;

  createTodo({ text });
  newTodoText.value = "";
}

function handleToggleTodo(id: Id<"todos">, completed: boolean) {
  toggleTodo({ id, completed: !completed });
}

function handleDeleteTodo(id: Id<"todos">) {
  deleteTodo({ id });
}
{{else}}
import { useQuery, useMutation, useQueryClient } from '@tanstack/vue-query'

const { $orpc } = useNuxtApp()

const newTodoText = ref('')
const queryClient = useQueryClient()

const todos = useQuery($orpc.todo.getAll.queryOptions())

const createMutation = useMutation($orpc.todo.create.mutationOptions({
  onSuccess: () => {
    queryClient.invalidateQueries()
    newTodoText.value = ''
  }
}))

const toggleMutation = useMutation($orpc.todo.toggle.mutationOptions({
  onSuccess: () => queryClient.invalidateQueries()
}))

const deleteMutation = useMutation($orpc.todo.delete.mutationOptions({
  onSuccess: () => queryClient.invalidateQueries()
}))

function handleAddTodo() {
  if (newTodoText.value.trim()) {
    createMutation.mutate({ text: newTodoText.value })
  }
}

function handleToggleTodo(id: number, completed: boolean) {
  toggleMutation.mutate({ id, completed: !completed })
}

function handleDeleteTodo(id: number) {
  deleteMutation.mutate({ id })
}
{{/if}}
</script>

<template>
  <div class="mx-auto w-full max-w-md py-10">
    <UCard>
      <template #header>
        <div>
          <div class="text-xl font-bold">Todo List</div>
          <div class="text-muted text-sm">Manage your tasks efficiently</div>
        </div>
      </template>
      <form @submit.prevent="handleAddTodo" class="mb-6 flex items-center gap-2">
        <UInput
          v-model="newTodoText"
          placeholder="Add a new task..."
          autocomplete="off"
          class="w-full"
          {{#if (eq backend "convex")}}
          :disabled="isCreatePending"
          {{/if}}
        />
        <UButton
          type="submit"
          {{#if (eq backend "convex")}}
          :disabled="isCreatePending || !newTodoText.trim()"
          {{/if}}
        >
          {{#if (eq backend "convex")}}
            <span v-if="isCreatePending">
              <UIcon name="i-lucide-loader-2" class="animate-spin" />
            </span>
            <span v-else>Add</span>
          {{else}}
            Add
          {{/if}}
        </UButton>
      </form>

      {{#if (eq backend "convex")}}
        <p v-if="error || deleteError" class="mb-4 text-red-500">
          Error: \{{ error?.message || deleteError?.message }}
        </p>
        <div v-if="isPending" class="flex justify-center py-4">
          <UIcon name="i-lucide-loader-2" class="animate-spin w-6 h-6" />
        </div>
        <p v-else-if="data?.length === 0" class="py-4 text-center">
          No todos yet. Add one above!
        </p>
        <ul v-else-if="data" class="space-y-2">
          <li
            v-for="todo in data"
            :key="todo._id"
            class="flex items-center justify-between rounded-md border p-2"
          >
            <div class="flex items-center gap-2">
              <UCheckbox
                :model-value="todo.completed"
                @update:model-value="() => handleToggleTodo(todo._id, todo.completed)"
                :id="`todo-${todo._id}`"
              />
              <label
                :for="`todo-${todo._id}`"
                :class="{ 'line-through text-muted': todo.completed }"
                class="cursor-pointer"
              >
                \{{ todo.text }}
              </label>
            </div>
            <UButton
              color="neutral"
              variant="ghost"
              size="sm"
              square
              @click="handleDeleteTodo(todo._id)"
              aria-label="Delete todo"
              icon="i-lucide-trash-2"
            />
          </li>
        </ul>
      {{else}}
        <div v-if="todos.status.value === 'pending'" class="flex justify-center py-4">
          <UIcon name="i-lucide-loader-2" class="animate-spin w-6 h-6" />
        </div>
        <p v-else-if="todos.status.value === 'error'" class="py-4 text-center text-red-500">
          Error: \{{ todos.error.value?.message || 'Failed to load todos' }}
        </p>
        <p v-else-if="todos.data.value?.length === 0" class="py-4 text-center">
          No todos yet. Add one above!
        </p>
        <ul v-else class="space-y-2">
          <li
            v-for="todo in todos.data.value"
            :key="todo.id"
            class="flex items-center justify-between rounded-md border p-2"
          >
            <div class="flex items-center gap-2">
              <UCheckbox
                :model-value="todo.completed"
                @update:model-value="() => handleToggleTodo(todo.id, todo.completed)"
                :id="`todo-${todo.id}`"
              />
              <label
                :for="`todo-${todo.id}`"
                :class="{ 'line-through text-muted': todo.completed }"
                class="cursor-pointer"
              >
                \{{ todo.text }}
              </label>
            </div>
            <UButton
              color="neutral"
              variant="ghost"
              size="sm"
              square
              @click="handleDeleteTodo(todo.id)"
              aria-label="Delete todo"
              icon="i-lucide-trash-2"
            />
          </li>
        </ul>
      {{/if}}
    </UCard>
  </div>
</template>
